package com.spring.boot.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spring.boot.dao.*;
import com.spring.boot.entity.*;
import com.spring.boot.service.ContractService;
import com.spring.boot.utils.ServiceException;
import com.spring.boot.vo.FindContractList;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author: Daniel ZTQ
 * @Date: 2021/01/01 22:59
 * @Description: 合同信息业务逻辑层 接口实现
 */
@Slf4j
@Service
public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> implements ContractService {
    @Autowired
    private ContractMapper contractMapper;

    @Autowired
    private InsurancePolicyMapper insurancePolicyMapper;

    @Autowired
    private CollectAndPayMapper collectAndPayMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private InsuranceMapper insuranceMapper;

    @Autowired
    private InsuredMapper insuredMapper;


    /**
     * 新增合同实现接口（普通用户）
     */
    @Override
    public Map<String, Object> addContract(Contract contract) {
        //定义map对象
        Map<String, Object> result = new HashMap<>();
        //创建保单对象
        InsurancePolicy insurancePolicy = new InsurancePolicy();
        //创建收付款对象
        CollectAndPay collectAndPay = new CollectAndPay();
        try {
            //生成合同
            //创建uuid
            String uuid = UUID.randomUUID().toString();
            //设置合同的uuid
            contract.setContractUuid(uuid);
            //设置合同建档时间
            contract.setCreatedTime(new Date());
            //设置状态为确认收款中
            contract.setType("1");
            //调用contractMapper层的insert的sql进行添加合同信息
            contractMapper.insert(contract);

            //生成保单信息
            //设置保单的uuid
            insurancePolicy.setInsurancePolicyUuid(UUID.randomUUID().toString());
            //根据uuid查询合同信息，获取合同id
            Integer contractId = contractMapper.getContractByContractUuid(uuid).getContractId();
            //设置保单表中的合同id
            insurancePolicy.setContractId(contractId.toString());
            //设置保单表中的险种id
            insurancePolicy.setInsuranceId(contract.getInsuranceId());
            //设置保单表中的被保险人id
            insurancePolicy.setInsuredId(contract.getInsuredId());
            //设置保单中的状态为生效中  保单状态  1： 保单生效状态 2：发起理赔（理赔） 3：已理赔
            insurancePolicy.setState("1");
            //获取被保险人id
            String insuredId = contract.getInsuredId();
            //获取被保险人身份证号
            String identityCard = insuredMapper.selectById(insuredId).getIdentityCard();
            //设置保单中的被保险人身份证号
            insurancePolicy.setInsuredIdCard(identityCard);
            //设置保单中的保单生效时间
            insurancePolicy.setEntryIntoForceTime(contract.getEntryIntoForceTime());
            //设置保单中的保单失效时间
            insurancePolicy.setExpirationTime(contract.getExpirationTime());
            //设置保单中的合同uuis
            insurancePolicy.setContractUuid(uuid);
            //获取险种id
            String insuranceId = contract.getInsuranceId();
            //根据险种id获取险种名称
            String insuranceName = insuranceMapper.selectById(insuranceId).getInsuranceName();
            //设置保单中的险种名称
            insurancePolicy.setInsuranceName(insuranceName);
            //调用insurancePolicyMapper层的insert方法，保存保单信息
            insurancePolicyMapper.insert(insurancePolicy);

            //生成支付记录
            //根据合同id查询保单信息，获取保单id
            Integer insurancePolicyId = insurancePolicyMapper.getInsurancePolicyByContractId(contractId.toString()).get(0).getInsurancePolicyId();
            //设置保单id
            collectAndPay.setInsurancePolicyId(insurancePolicyId.toString());
            //设置收到的购买险种金额
            collectAndPay.setMoney(contract.getAmountActuallyPaid());
            //设置收支类型 0：收款 1：付款（理赔）
            collectAndPay.setType("0");
            //设置建档时间
            collectAndPay.setCreatedTime(new Date());
            //调用collectAndPayMapper中的insert方法，进行保存收付款信息
            collectAndPayMapper.insert(collectAndPay);

            //日志打印
            log.info("新增合同成功！");
            //设置状态码
            result.put("code", 200);
            //设置msg值
            result.put("msg", "新增合同成功！");
            //设置status值
            result.put("status", true);
        } catch (Exception e) {
            //日志打印"新增合同调用接口失败"
            log.error("新增合同调用接口失败", e);
            //设置状态码
            result.put("code", 500);
            //设置msg值
            result.put("msg", "新增合同调用接口失败！");
            //设置status值
            result.put("status", false);
            //抛出异常
            throw new ServiceException("新增合同调用接口失败");
        }
        return result;
    }


    /**
     * 删除合同实现接口（没有用到）
     */
    /*@Override
    public Map<String, Object> deleteBatchIdsContract(String contractId) {
        //定义map对象
        Map<String, Object> result = new HashMap<>();
        try {
            //以逗号分隔
            String[] split = contractId.split(",");
            //创建list集合
            List<String> idList = new ArrayList<>();
            //for循环遍历，以逗号分隔 要删除的合同
            for (String str : split) {
                //将要删除的合同信息 放入list集合里面
                idList.add(str);
            }
            //调用contractMapper层的deleteBatchIds的sql，批量删除合同
            contractMapper.deleteBatchIds(idList);
            //设置msg值
            result.put("msg", "删除合同信息成功！");
            //设置status值
            result.put("status", true);
        } catch (Exception e) {
            //日志打印“合同信息删除失败”
            log.error("合同信息删除失败");
            //设置msg值
            result.put("msg", "合同信息失败！");
            //设置status值
            result.put("status", false);
            //抛出异常
            throw new ServiceException("合同信息删除失败");
        }
        //返回结果
        return result;
    }*/


    /**
     * 修改合同实现接口（没有用到）
     */
    /*@Override
    public Map<String, Object> updateContract(Contract contract) {
        //定义map对象
        Map<String, Object> result = new HashMap<>();
        try {
            //调用contractMapper层的updateById的sql修改合同信息
            contractMapper.updateById(contract);
            //设置msg值
            result.put("msg", "修改成功！");
            //设置status值
            result.put("status", true);
        } catch (Exception e) {
            //日志打印“合同信息修改失败”
            log.error("合同修改信息接口失败");
            //设置msg值
            result.put("msg", "合同修改信息接口失败！");
            //设置status值
            result.put("status", false);
            //抛出异常
            throw new ServiceException("合同修改信息接口失败");
        }
        //返回结果
        return result;
    }*/


    /**
     * 查询合同详情
     */
    @Override
    public Map<String, Object> findContractDetails(String contractUuid) {
        //定义map对象
        Map<String, Object> result = new HashMap<>();
        //创建一个Contract类的的list对象
        List<Contract> allContract = new ArrayList<Contract>();
        try {
            //根据合同uuid查询合同信息
            Contract contractByContractUuid = contractMapper.getContractByContractUuid(contractUuid);
            //定义返回data对象
            Map<String, Object> resultData = new HashMap<>();
            //获取险种id
            String insuranceId = contractByContractUuid.getInsuranceId();
            //根据险种id获取险种信息
            Insurance insuranceByinsuranceId = insuranceMapper.getInsuranceByinsuranceId(insuranceId);
            //设置获取到的险种名称
            resultData.put("insuranceName", insuranceByinsuranceId.getInsuranceName());
            //设置获取到的险种价位
            resultData.put("InsurancePrice", insuranceByinsuranceId.getInsurancePrice());
            //设置获取到的险种说明
            resultData.put("insuranceExplain", insuranceByinsuranceId.getInsuranceExplain());
            //设置获取到的险种时效
            resultData.put("insurancePrescription", insuranceByinsuranceId.getInsurancePrescription());

            //设置获取被保险人id
            String insuredId = contractByContractUuid.getInsuredId();
            //设置根据被保险人id获取被保险人信息
            Insured insured = insuredMapper.selectById(insuredId);
            //设置被保险人姓名
            resultData.put("insuredName", insured.getName());
            //设置被保险人手机号
            resultData.put("insuredMobile", insured.getMobile());
            //设置被保险人身份证号
            resultData.put("insuredIdentityCard", insured.getIdentityCard());
            //设置被保险人家庭地址
            resultData.put("insuredAddress", insured.getAddress());
            //设置被保险人性别
            resultData.put("insuredSex", insured.getSex());


            //设置获取投保人用户id
            String uid1 = contractByContractUuid.getUid();
            //设置获取投保人信息
            User userByUid = userMapper.getUserByUid(uid1);
            //设置获取到的投保人身份证号
            resultData.put("userIdCard", userByUid.getIdCard());
            //设置获取到的投保人手机号
            resultData.put("userMobile", userByUid.getMobile());
            //设置获取到的投保人性别
            resultData.put("userGender", userByUid.getGender());
            //设置获取到的投保人地址
            resultData.put("userAddress", userByUid.getAddress());
            //设置获取到的投保人姓名
            resultData.put("userName", userByUid.getUserName());

            //设置获取合同id
            Integer contractId = contractByContractUuid.getContractId();
            //设置获取到的合同信息
            Contract contractBycontractId = contractMapper.getContractBycontractId(contractId);
            //设置获取到的合同创建时间
            resultData.put("createdTime", contractBycontractId.getCreatedTime());
            //设置获取到的合同生效日期
            resultData.put("entryIntoForceTime", contractBycontractId.getEntryIntoForceTime());
            //设置获取到的合同失效日期
            resultData.put("expirationTime", contractBycontractId.getExpirationTime());
            //设置获取到的合同状态
            resultData.put("type", contractBycontractId.getType());
            //设置获取到的合同uuid
            resultData.put("contractUuid", contractBycontractId.getContractUuid());
            //打印日志
            log.info("查询合同成功");
            //设置状态码
            result.put("code", 200);
            //设置data值
            result.put("data", resultData);
            //设置msg值
            result.put("msg", "查询合同信息成功");
            //设置status值
            result.put("status", true);
        } catch (Exception e) {
            //打印日志
            log.error("根据合同uuid查询合同信息失败:", e);
            //设置状态码
            result.put("code", 500);
            //设置msg值
            result.put("msg", "调用根据根据合同uuid查询合同接口失败！");
            //设置status值
            result.put("status", false);
            throw new ServiceException("调用根据根据合同uuid查询合同接口失败！");
        }
        //返回结果
        return result;
    }

    /**
     * 财务确认收款接口
     */
    @Override
    public Map<String, Object> updateContractType(String contractUuid) {
        //定义map对象
        Map<String, Object> result = new HashMap<>();
        try {
            //根据合同uuid，进行修改合同状态，状态为确认收款
            int i = contractMapper.updateContractType("2", contractUuid);
            //如果成功修改
            if (i > 0) {
                //设置返回码
                result.put("code", 200);
                //设置msg值
                result.put("msg", "确认收款成功!");
                //设置status值
                result.put("status", true);
            }
        } catch (Exception e) {
            //打印日志
            log.error("确认收款失败:", e);
            //设置返回码
            result.put("code", 500);
            //设置msg值
            result.put("msg", "确认收款调用接口失败！");
            //设置status值
            result.put("status", false);
        }
        return result;
    }

    /**
     * 查询合同列表
     */
    @Override
    public Map<String, Object> findContractList(FindContractList findContractList) {
        String uid = findContractList.getUid();
        //定义map对象
        Map<String, Object> result = new HashMap<>();
        //创建一个list对象
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        //创建一个Contract类的的list对象
        List<Contract> allContract = new ArrayList<Contract>();
        try {
            //根据用户id查询用户信息
            User userByUid = userMapper.getUserByUid(uid);
            //获取该用户的角色  0：管理员   2：普通用户
            String role = userByUid.getRole();
            //如果是普通用户
            if ("2".equals(role)) {
                //如果前端没有传type
                if (StringUtils.isBlank(findContractList.getType())) {
                    //根据用户id查询合同信息
                    allContract = contractMapper.getContractByContractUid(uid);
                } else {
                    //如果传了type
                    String type = findContractList.getType();
                    //调用sql，根据用户id和合同状态获取合同信息
                    allContract = contractMapper.getContractByContractUidAndType(uid, type);
                }
            } else {
                //如果是管理员或财务人员
                //如果没有传type
                if (StringUtils.isBlank(findContractList.getType())) {
                    //查询所有合同
                    allContract = contractMapper.getAllContract();
                } else {
                    //如果传了type
                    String type = findContractList.getType();
                    //调用sql，根据合同状态获取合同信息
                    allContract = contractMapper.getContractBytype(type);
                }
            }
            //将获取到的list进行遍历 （合同信息）
            for (int i = 0; i < allContract.size(); i++) {
                Map<String, Object> resultData = new HashMap<>();
                //获取险种id
                String insuranceId = allContract.get(i).getInsuranceId();
                //根据险种id获取险种信息
                Insurance insuranceByinsuranceId = insuranceMapper.getInsuranceByinsuranceId(insuranceId);
                //设置获取到的险种名称
                resultData.put("insuranceName", insuranceByinsuranceId.getInsuranceName());

                //设置获取被保险人id
                String insuredId = allContract.get(i).getInsuredId();
                //设置根据被保险人id获取被保险人信息
                Insured insured = insuredMapper.selectById(insuredId);
                //设置被保险人姓名
                resultData.put("insuredName", insured.getName());

                //设置获取投保人信息
                User userByUid1 = userMapper.getUserByUid(uid);
                //设置获取到的投保人姓名
                resultData.put("userName", userByUid1.getUserName());

                //设置获取合同id
                Integer contractId = allContract.get(i).getContractId();
                //设置获取到的合同信息
                Contract contractBycontractId = contractMapper.getContractBycontractId(contractId);
                //设置获取到的合同生效日期
                resultData.put("entryIntoForceTime", contractBycontractId.getEntryIntoForceTime());
                //设置获取到的合同失效日期
                resultData.put("expirationTime", contractBycontractId.getExpirationTime());
                //设置获取到的合同状态
                resultData.put("type", contractBycontractId.getType());
                //设置获取到的合同uuid
                resultData.put("contractUuid", contractBycontractId.getContractUuid());
                //添加数据
                list.add(resultData);
            }
            //打印日志
            log.info("查询合同成功");
            //设置状态码
            result.put("code", 200);
            //设置data值
            result.put("data", list);
            //设置msg值
            result.put("msg", "查询合同信息成功");
            //设置status值
            result.put("status", true);
        } catch (Exception e) {
            //打印日志
            log.error("根据用户id查询合同信息失败:", e);
            //设置状态码
            result.put("code", 500);
            //设置msg值
            result.put("msg", "调用根据用户id查询合同接口失败！");
            //设置status值
            result.put("status", false);
            throw new ServiceException("调用根据用户id查询合同接口失败！");
        }
        //返回结果
        return result;
    }


    /**
     * 同步过期合同和保单
     */
    @Override
    public void synchronizationExpiration() {
        //日期格式
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        //获取当前日期
        String format = formatter.format(new Date());
        //获取所有合同列表
        List<Contract> allContract = contractMapper.getAllContract();
        //进行for循环遍历
        for (int i = 0; i < allContract.size(); i++) {
            //判断合同是否超过失效日期
            int result = allContract.get(i).getExpirationTime().compareTo(format);
            //如果失效
            if (result < 0) {
                //获取合同的uuid
                String contractUuid = allContract.get(i).getContractUuid();
                //获取合同id
                Integer contractId = allContract.get(i).getContractId();
                //修改保单状态
                insurancePolicyMapper.updateSynchronizationState(contractId.toString());
                //修改合同状态
                contractMapper.updateContractType("3", contractUuid);
            }
        }
    }

    /**
     * 根据合同uuid查询合同实现接口（没有用到）
     */
   /* @Override
    public Map<String, Object> findContractByUuid(String contractUuid) {
        //定义map对象
        Map<String, Object> result = new HashMap<>();
        try {
            List<Contract> contractByUid = contractMapper.getContractByContractUuid(contractUuid);
            //设置msg值
            result.put("msg", contractByUid);
            //设置status值
            result.put("status", true);
        } catch (Exception e) {
            //打印日志
            log.error("查询合同信息失败:", e);
            //设置msg值
            result.put("msg", "调用查询合同信息接口失败！");
            //设置status值
            result.put("status", false);
            throw new ServiceException("调用查询合同信息接口失败！");
        }
        return result;
    }*/
}
